﻿using System.Linq;
using System.Windows.Forms;
using Autofac;
using ComputerVision.BaseForm;
using ComputerVision.Common;
using ComputerVision.Data;
using ComputerVision.Services;
using Emgu.CV;
using Emgu.CV.Structure;
using System;
using System.Drawing;

namespace ComputerVision
{
    public partial class frmXeRa : frmObject
    {
        private IService<ConfigrationCamera> _configCamera;
        private IService<LoaiXe> _loaiXe;
        private IService<VeXe> _veXe;
        private IService<Xe> _xe;
        private readonly Common.ImageProcess _process;
        private Capture cap2;
        private Capture cap3;
        private int _cmr2;
        private int _cmr3;
        private Image<Bgr, byte> img2; //nhận diện mặt người ra                
        private Bitmap img2end=null; //nhận diện mặt người ra                
        private Image<Bgr, byte> img3; //nhận diện mặt người ra                
        private Bitmap img3end = null; //nhận diện mặt người ra                
        private Image<Gray, byte> imgGray2;
        private Image<Bgr, Byte> biensoxera;
        private string _computerName;
        string bienso;
        private System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("\\d\\d-[A-Z][0-9A-Z]-\\d{4,5}");
        private System.Text.RegularExpressions.Regex regexoto = new System.Text.RegularExpressions.Regex("\\d\\d-[A-Z]-\\d{4,5}");
        private string _soVe;

        public frmXeRa()
        {
            InitializeComponent();
            _computerName = Environment.MachineName;
            _configCamera = Program.Container.Resolve<IService<ConfigrationCamera>>();
            _loaiXe = Program.Container.Resolve<IService<LoaiXe>>();
            _xe = Program.Container.Resolve<IService<Xe>>();
            _veXe = Program.Container.Resolve<IService<VeXe>>();
            _process = new ImageProcess();
            _soVe = txtSoVe.Text;
            GetConfigCamera(_computerName);
            LoadLoaiXe();
        }
        
        private void CaptureWC()
        {
            //_cmr2 = 0;
            cap2 = new Capture(_cmr3);
            cap2.ImageGrabbed += wc2;
            cap2.Start();

            //_cmr3 = 0;
            cap3 = new Capture(_cmr2);
            cap3.ImageGrabbed += wc1detectFace;
            cap3.Start();
        }

        private void wc1detectFace(object sender, EventArgs e)
        {
            var faceDetector1 = new CascadeClassifier("haarcascade_frontalface_default.xml");
            img2 = cap3.RetrieveBgrFrame();
            imgGray2 = img2.Convert<Gray, byte>();
            foreach (var face in faceDetector1.DetectMultiScale(imgGray2, 1.1, 10, new Size(20, 20), Size.Empty))
            {
                img2.Draw(face, new Bgr(Color.White), 1);
            }
            //imgRaTruoc.Image = img2;
            picRaTruoc.Image = img2.Bitmap;
        }

        private void wc2(object sender, EventArgs e)
        {
            try
            {
                img3 = cap2.RetrieveBgrFrame();
                //imgRaSau.Image = img3;
                picRaSau.Image = img3.Bitmap;
            }
            catch (Exception ex)
            {

            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (Timer_Ra.Enabled == false)
            {
                Timer_Ra.Enabled = true;
                picBiensora.Image = null;
                btnDocLai.Text = @"Ngừng";
                lblTrangThai.Text = Constants.StatusReading.Reading;
                lblTrangThai.ForeColor = Color.Blue;
            }
            else
            {
                Timer_Ra.Enabled = false;
                picBiensora.Image = null;
                btnDocLai.Text = @"Đọc tiếp";
                lblTrangThai.Text = Constants.StatusReading.Stopped;
                lblTrangThai.ForeColor = Color.Red;
            }
        }

        private void frmXeRa_Load(object sender, System.EventArgs e)
        {
            CaptureWC();
        }

        private void Timer_Ra_Tick(object sender, EventArgs e)
        {
            biensoxera = new Image<Bgr, Byte>(img3.Bitmap);
          //  bienso = _process.docbienso(biensoxera, picBiensora);
            if (regex.IsMatch(bienso))
            {
                Timer_Ra.Enabled = false;
                //  picTruoc.Image = imgVaoTruoc.Image.Bitmap;
                //  picTruoc.Visible = true;
                //  picSau.Image = imgVaoSau.Image.Bitmap;
                //  picSau.Visible = true;
                img2end = img2.ToBitmap();
                img3end = img3.ToBitmap();
                txtBiensora.Text = bienso;
                foreach (LoaiXe loaiXe in cbLoaixe.Items)
                {
                    if (loaiXe.Ten.ToUpper().Equals(Constants.Xe.XeMay.ToUpper()))
                    {
                        cbLoaixe.SelectedItem = loaiXe;
                        break;
                    }
                }
                //  btnDoclai.Text = "Đọc tiếp";
                //  MarqueeProgressBarControl1.Enabled = false;
                //  cbLoaixevao.SelectedItem = "Xe máy";
                //  txtNgayvao.Text = DateAndTime.Now.ToString("dd/MM/yyyy");
                // txtGiovao.Time = DateAndTime.Now;
                lblTrangThai.Text = Constants.StatusReading.Stopped;
                lblTrangThai.ForeColor = Color.Red;
                btnDocLai.Text = @"Đọc tiếp";
            }
            else if (regexoto.IsMatch(bienso))
            {
                Timer_Ra.Enabled = false;
                txtBiensora.Text = bienso;
                img2end = img2.ToBitmap();
                img3end = img3.ToBitmap();
                foreach (LoaiXe loaiXe in cbLoaixe.Items)
                {
                    if (loaiXe.Ten.ToUpper().Equals(Constants.Xe.Oto.ToUpper()))
                    {
                        cbLoaixe.SelectedItem = loaiXe;
                        break;
                    }
                }

                lblTrangThai.Text = Constants.StatusReading.Stopped;
                lblTrangThai.ForeColor = Color.Red;
                btnDocLai.Text = @"Đọc tiếp";
            }
        }

        private void GetConfigCamera(string name)
        {
            var items = _configCamera.ToList().ToList().Where(p => p.ComputerName.Contains(name)).OrderBy(a => a.Name).ToList();

            var item = items.FirstOrDefault(p => p.Name.Contains(Constants.CameraPosition.First));
            if (item != null)
            {
                _cmr2 = (item.DeviceId != null) ? (int)item.DeviceId : 0;
            }

            item = items.FirstOrDefault(p => p.Name.Contains(Constants.CameraPosition.Second));
            if (item != null)
            {
                _cmr3 = (item.DeviceId != null) ? (int)item.DeviceId : 0;

            }
        }

        private void LoadLoaiXe()
        {
            var loaixe = _loaiXe.ToList().ToList();
            foreach (LoaiXe loai in loaixe)
            {
                cbLoaixe.Items.Add(loai);
            }
        }

        #region Validation

        private void ValidCard()
        {
            int result;
            bool flag1 = true;
            bool flag2 = true;

            flag1 = int.TryParse(txtSoVe.Text, out result);
            var soVe = _veXe.Detail(result);
            flag2 = (soVe != null);

            if (flag1 && flag2)
            {
                lblTrangThaiThe.Text = @"Vé hợp lệ";
                lblTrangThaiThe.ForeColor = Color.Blue;
            }
            else
            {
                lblTrangThaiThe.Text = @"Vé không hợp lệ";
                lblTrangThaiThe.ForeColor = Color.Red;
            }
        }

        protected bool Validator()
        {
            if (string.IsNullOrEmpty(txtSoVe.Text))
            {
                AlertList.Error("Bạn chưa nhập số vé. Xin vui lòng kiểm tra lại.");
                txtSoVe.Focus();
                return false;
            }

            int result;
            if (!int.TryParse(txtSoVe.Text, out result))
            {
                AlertList.Error("Bạn nhập số vé không hợp lệ. Xin vui lòng kiểm tra lại");
                txtSoVe.Focus();
                return false;
            }

            var soVe = _veXe.Detail(result);
            if (soVe == null)
            {
                AlertList.Error("Bạn nhập số vé không có trong dữ liệu. Xin vui lòng kiểm tra lại");
                txtSoVe.Focus();
                return false;
            }

            if (cbLoaixe.SelectedItem == null)
            {
                AlertList.Error("Bạn chưa chọn loại xe. Xin vui lòng kiểm tra lại.");
                cbLoaixe.Focus();
                return false;
            }

            var loaiXe = cbLoaixe.SelectedItem as LoaiXe;

            if (!loaiXe.Ten.ToUpper().Equals(Constants.Xe.XeDap.ToUpper()) && string.IsNullOrEmpty(txtBiensora.Text))
            {
                AlertList.Error("Bạn chưa nhập biển số xe ra. Xin vui lòng kiểm tra lại.");
                txtBiensora.Focus();
                return false;
            }

            if (!txtBienSoVao.Text.Replace("-", "").Replace(".", "").ToUpper().Equals(txtBiensora.Text.Replace("-", "").Replace(".", "").ToUpper()))
            {
                AlertList.Error("Biển số ra và vào không giống nhau. Xin vui lòng kiểm tra lại.");
                txtBiensora.Focus();
                return false;
            }

            return true;
        }

        #endregion

        private void btnTiep_Click(object sender, EventArgs e)
        {
            if (Validator())
            {
                Edit(int.Parse(txtSoVe.Text));
            }
        }

        private void timerClock_Tick(object sender, EventArgs e)
        {
            dtpGioRa.Value = DateTime.Now;
            dtpNgayRa.Value = DateTime.Now;
            //valid card
            if (!txtSoVe.Text.Trim().Equals(string.Empty) && !txtSoVe.Text.Trim().Equals(_soVe))
            {
                ValidCard();
                _soVe = txtSoVe.Text.Trim();
            }
        }

        #region Edit

        protected void Edit(int soVe)
        {
            //var item = _xe.ToList().ToList()
            //    .Where(p => p.SoVe.Equals(soVe))
            //    .OrderByDescending(b => b.NgayVao)
            //    .ThenByDescending(c => c.GioVao)
            //    .FirstOrDefault(a => a.BienSoXe.Equals(bienSoXe));

            var item = _xe.ToList().ToList()
                    .OrderByDescending(b => b.NgayVao)
                    .FirstOrDefault(p => p.SoVe.Equals(soVe));
            if (item != null)
            {
                item.NgayRa = DateTime.Now;
                item.ImgRaTruoc = ImageProcess.ConvertToByteArray(img2end);
                item.ImgRaSau = ImageProcess.ConvertToByteArray(img3end);
                item.ImgBienXeRa = ImageProcess.ConvertToByteArray(biensoxera.Bitmap);
                item.Modified = DateTime.Now;
                item.ModifiedBy = Constants.CurrentUser;
                _xe.Update(item);

                //Reset controls
                txtSoVe.Text = string.Empty;
                txtBienSoVao.Text = string.Empty;
                dtpGioVao.Text = string.Empty;
                dtpNgayRa.Text = string.Empty;
                txtBiensora.Text = string.Empty;
                txtSoVe.Focus();
            }
        }

        #endregion

        private void txtSoVe_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (!string.IsNullOrEmpty(txtSoVe.Text.Trim()))
                {
                    int result;
                    if (!int.TryParse(txtSoVe.Text, out result))
                    {
                        AlertList.Error("Bạn nhập số vé không hợp lệ. Xin vui lòng kiểm tra lại");
                        txtSoVe.Focus();
                        return;
                    }

                    var soVe = _veXe.Detail(result);
                    if (soVe == null)
                    {
                        AlertList.Error("Bạn nhập số vé không có trong dữ liệu. Xin vui lòng kiểm tra lại");
                        txtSoVe.Focus();
                        return;
                    }

                    var item = _xe.ToList().ToList()
                        .OrderByDescending(b => b.NgayVao)
                        .FirstOrDefault(p => p.SoVe.Equals(int.Parse(txtSoVe.Text.Trim())));
                    if (item != null)
                    {
                        txtBienSoVao.Text = item.BienSoXe;
                        dtpGioVao.Value = ((item.NgayVao.HasValue) ? item.NgayVao.Value : DateTime.Today);
                        dtpNgayvao.Value = ((item.NgayVao.HasValue) ? item.NgayVao.Value : DateTime.Today);
                        picBienSoVao.Image = ImageProcess.ConvertBytesToImg(item.ImgBienXeVao);
                        imgVaoTruoc.Image = ImageProcess.ConvertBytesToImg(item.ImgVaoTruoc);
                        imgVaoSau.Image = ImageProcess.ConvertBytesToImg(item.ImgVaoSau);

                    }
                }
            }
        }

        private void txtSoVe_MouseEnter(object sender, EventArgs e)
        {
            txtSoVe.SelectAll();
        }

        private void txtSoVe_MouseDown(object sender, MouseEventArgs e)
        {
            txtSoVe.SelectAll();

        }
        
        private void txtSoVe_TextChanged(object sender, EventArgs e)
        {
            if (txtSoVe.Text.Length == 10)
            {
                txtSoVe.SelectAll();
            }
        }

    }
}
